package com.novatec.mvc.controlador;

import java.lang.reflect.InvocationTargetException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.novatec.dao.CajasDAO;
import com.novatec.dao.ClientesDAO;
import com.novatec.dao.ContratosDAO;
import com.novatec.dao.UtilsDAO;
import com.novatec.dao.VendedoresDAO;
import com.novatec.mvc.forms.ContratoForm;
import com.novatec.mvc.modelo.ContratoItem;
import com.novatec.mvc.modelo.DetalleContratoItem;
import com.novatec.mvc.servicio.ContratosService;

@Controller
public class Contrato {

	private final Logger logger = Logger.getLogger(this.getClass());

	@Autowired
	private ContratosService contratosService;
	@Autowired
	private ClientesDAO clientesDAO;
	@Autowired
	private CajasDAO cajasDAO;
	@Autowired
	private VendedoresDAO vendedoresDAO;
	@Autowired
	private UtilsDAO utilsDAO;
	@Autowired
	private ContratosDAO contratosDAO;

	
	@RequestMapping(value = "/contrato", method = RequestMethod.GET, params="!contratoId")
	public ModelAndView regContrato() throws ParseException {
		
		logger.debug("inicio: contrato");
		ContratoForm contratoForm= new ContratoForm();
		contratoForm.setIdContrato(utilsDAO.getID("CONTRATO"));
		ModelAndView formRegContrato= new ModelAndView("formRegContrato", "formRegContrato", contratoForm);
		List<DetalleContratoItem> detalleContrato = new ArrayList<DetalleContratoItem>();
		detalleContrato.add(new DetalleContratoItem());
		
		formRegContrato.addObject("listaTipoCaja", cajasDAO.getListaTipCajas());
		formRegContrato.addObject("detalleContrato", detalleContrato);
		
		//fvilla 17-04-2012 ini
		
		formRegContrato.addObject("vendedoresAll",getVendedoresAll());
		
		//fvilla 17-04-2012 fin				
		
		return formRegContrato;
	}

	@RequestMapping(value = "/contrato", method = RequestMethod.GET, params="contratoId")
	public ModelAndView updContrato(@RequestParam(value="contratoId", required=true) Long idContrato) throws ParseException, DataAccessException, IllegalAccessException, InvocationTargetException {
		
		logger.debug("inicio: contrato update");
		ModelAndView formUpdContrato= new ModelAndView("formUpdContrato", "formUpdContrato", contratosDAO.getContratoById(idContrato));
		
		formUpdContrato.addObject("listaTipoCaja", cajasDAO.getListaTipCajas());
		formUpdContrato.addObject("detalleContrato", contratosDAO.getDetalleContratoById(idContrato));
		return formUpdContrato;
	}
	
	@RequestMapping(value = "/registrarContrato", method = RequestMethod.POST)
	public ModelAndView crearContrato(@ModelAttribute("formRegContrato") ContratoForm contratoForm, 
	
			@RequestParam(value="saldoContable") Long[] saldosContable,
			@RequestParam(value="idTipoCaja") Long[] idsTipoCaja,
			@RequestParam(value="precioCaja") Float[] preciosCaja,
			@RequestParam(value="idMoneda") Long[] idsMoneda
			) {

	    
		logger.debug("inicio: contrato new");
		List<DetalleContratoItem> detalleContrato= new ArrayList<DetalleContratoItem>();
		for (int i = 0; i < saldosContable.length; i++) {
			DetalleContratoItem detalle= new DetalleContratoItem();
			detalle.setIdTipoCaja(idsTipoCaja[i]);
			detalle.setSaldoDisponible(saldosContable[i]);
			detalle.setSaldoContable(saldosContable[i]);
			detalle.setPrecioCaja(preciosCaja[i]);
			detalle.setIdMoneda(idsMoneda[i]);
			detalleContrato.add(detalle);
		}
		ModelAndView formRegContrato= new ModelAndView("formRegContrato", "formRegContrato", contratoForm);
		try {
			contratoForm.setDetalleContrato(detalleContrato);
			//Recuperar idCliente
			contratoForm.setIdCliente(clientesDAO.getIdUsuarioByRucDNI(contratoForm.getRuc_dni()));
			if(!contratosService.validarVigencia(contratoForm)){
				formRegContrato.addObject("flagVigencia", true);
				return formRegContrato;
			}
			contratosService.guardarContrato(contratoForm);
			return new ModelAndView("redirect:formCrearContratoOk");
		} catch (Exception e) {
			logger.error(e.getMessage());
			formRegContrato.addObject("flagException", true);
			return formRegContrato;
		}
		
	}
	@RequestMapping("/formCrearContratoOk")
	public String formCrearContratoOk() {
		return "formCrearContratoOk";
	}
	
	@RequestMapping(value = "/actualizarContrato", method = RequestMethod.POST)
	public ModelAndView actualizarContrato(@ModelAttribute("formUpdContrato") ContratoForm contratoForm, 
			
			@RequestParam(value="saldoContable") Long[] saldosContable,
			@RequestParam(value="idTipoCaja") Long[] idsTipoCaja,
			@RequestParam(value="precioCaja") Float[] preciosCaja,
			@RequestParam(value="idMoneda") Long[] idsMoneda
	) {
		
		
		logger.debug("inicio: contrato update");
//		List<DetalleContratoItem> detalleContrato= new ArrayList<DetalleContratoItem>();
//		for (int i = 0; i < saldosContable.length; i++) {
//			DetalleContratoItem detalle= new DetalleContratoItem();
//			detalle.setIdTipoCaja(idsTipoCaja[i]);
//			detalle.setSaldoDisponible(saldosContable[i]);
//			detalle.setSaldoContable(saldosContable[i]);
//			detalle.setPrecioCaja(preciosCaja[i]);
//			detalle.setIdMoneda(idsMoneda[i]);
//			detalleContrato.add(detalle);
//		}
		ModelAndView formUpdContrato= new ModelAndView("formUpdContrato", "formUpdContrato", contratoForm);
		try {
//			contratoForm.setDetalleContrato(detalleContrato);
			//Recuperar idCliente
			contratoForm.setIdCliente(clientesDAO.getIdUsuarioByRucDNI(contratoForm.getRuc_dni()));

			contratosService.actualizarContrato(contratoForm);
			return new ModelAndView("redirect:formActualizarContratoOk");
		} catch (Exception e) {
			logger.error(e.getMessage());
			formUpdContrato.addObject("flagException", true);
			return formUpdContrato;
		}
		
//		return formUpdContrato;
	}
	@RequestMapping("/formActualizarContratoOk")
	public String formActualizarContratoOk() {
		return "formActualizarContratoOk";
	}
	
	@RequestMapping(value="/ajaxGetCliente", method=RequestMethod.POST)
	public @ResponseBody Map<String, ?> getCliente(@RequestBody String cliente){
		logger.debug("get Cliente: "+ cliente);
		
		return clientesDAO.getClienteByRUCDNI(cliente);
	}
	
	@RequestMapping(value="/getVendedores", method=RequestMethod.GET)
	public @ResponseBody String getVendedores(@RequestParam("vendedor") String vendedor){
		logger.debug("get Vendedores: "+ vendedor);
		String vendedores= "";
	    for (Map<String, Object> vendedorMap : vendedoresDAO.getVendedoresLikeNick(vendedor)) {
	    	Long idVendedorLong= (Long) vendedorMap.get("idVendedor");
	    	String vendedorString= (String) vendedorMap.get("vendedor");
	    	vendedores+= vendedores.isEmpty()?vendedorString+"|"+idVendedorLong:"\n"+vendedorString+"|"+idVendedorLong; 
		}
		return vendedores;
	}

	//fvilla 13-04-2012 ini
	@RequestMapping(value="/getVendedoresAll", method=RequestMethod.GET)
	public @ResponseBody List<Map<String, Object>> getVendedoresAll(){
		logger.debug("get VendedoresAll: ");

		List<Map<String, Object>> vendedorMap =  vendedoresDAO.getVendedoresAll();
		return vendedorMap;
	}	
	//fvilla 13-04-2012 fin
		
	@RequestMapping(value="/getClientes", method=RequestMethod.GET)
	public @ResponseBody String getClientes(@RequestParam("ruc_dni") String ruc_dni){
		logger.debug("get Clientes: "+ ruc_dni);
		String clientes= "";
		for (Map<String, Object> clienteMap : clientesDAO.getClientesLikeRUCDNI(ruc_dni)) {
			String clienteString= (String) clienteMap.get("ruc_dni");
			clientes+= clientes.isEmpty()?clienteString:"\n"+clienteString; 
		}
		return clientes;
	}
	
	@RequestMapping("/listacontratos")
	public ModelAndView listaContratos() {
		ModelAndView mav = new ModelAndView("formListaContratos");

		List<ContratoItem> lista = contratosDAO.getAllContratos();
		
		mav.addObject("lista", lista);

		return mav;
	}

	@RequestMapping("/filtroContrato")
	public ModelAndView listaFiltradaContratos(@RequestParam("dni") String dni, @RequestParam("nocontrato") String nocontrato, @RequestParam("razsoc") String razsoc, @RequestParam("vencimiento") String vencimiento) {
		ModelAndView mav = new ModelAndView("formListaContratos");

		List<ContratoItem> listabase = contratosDAO.getAllContratos();
		List<ContratoItem> lista = new ArrayList<ContratoItem>();

		String contrato;
		String nombreRazonSocial;
		float alerta;

		

		for (int i = 0; i < listabase.size(); i++){
			ContratoItem ci = listabase.get(i);
			contrato = ci.getIdContrato().toString().substring(0, nocontrato.length());
			nombreRazonSocial = ci.getNombreRazonSocial().substring(0, razsoc.length());

			if (contrato.equals(nocontrato) && contrato.length() > 0)
				lista.add(ci);
			if (nombreRazonSocial.equals(razsoc) && !lista.contains(ci) && nombreRazonSocial.length() > 0)
				lista.add(ci);
			if (validarNumeros(vencimiento) && !lista.contains(ci)){
				alerta = Float.parseFloat(vencimiento);
				if (ci.getAlertaVigencia() == alerta)
					lista.add(ci);
			}			
		}

		mav.addObject("lista", lista);

		return mav;
	}

	public boolean validarNumeros(String str) {
        
        if (str == null || str.length() == 0)
            return false;
        
        for (int i = 0; i < str.length(); i++) {
            if (!Character.isDigit(str.charAt(i)))
                return false;
        }
        
        return true;
    }
	

}
